www.gusucode.com > 《C++高级语言程序设计》PPT及全书例子源代码-源码程序 > 《C++高级语言程序设计》PPT及全书例子源代码-源码程序/code/C++例题程序/第4章/复件 s4_12/sclass4_12_Node.cpp
//Download by http://www.NewXing.com //类的实现文件 //文件名:ch4_12\sclass4_12_Node.cpp #include "sclass4_12_Node.h" /*包含类定义头文件*/ //Node无参构造函数 //Node::Node() //{ // m_lpszChar = NULL; // m_iValue = 0; // cout << "调用了无参构造函数Node: " << endl; //} //Node带参构造函数 Node::Node(char *lpszChar, int iValue) //节点构造函数 { m_lpszChar = new char[strlen(lpszChar)+1]; //new节点名字空间。 if( m_lpszChar==NULL ) { cout << "内存分配失败。" << endl; exit(1); //内存分配失败,退出。 } strcpy(m_lpszChar, lpszChar); m_iValue = iValue; //节点值初为0 cout << "调用了带参构造函数Node: " << m_lpszChar << endl; } //Node的拷贝构造函数 Node::Node(const Node &oNode) { m_lpszChar = new char[strlen(oNode.m_lpszChar)+1]; //new节点名字空间。 if( m_lpszChar==NULL ) { cout << "内存分配失败。" << endl; exit(1); } strcpy(m_lpszChar, oNode.m_lpszChar); m_iValue = oNode.m_iValue; //节点值初为0 cout << "调用了拷贝构造函数Node:" << m_lpszChar << endl; } //Node的析构函数 Node::~Node() { cout << "调用了析构函数Node: " << m_lpszChar << endl; delete m_lpszChar; //当m_lpszChar==NULL时,也可以delete,不会出错。 } //Node的赋值运算符重载 Node & Node::operator=(const Node &oNode) { if (this == &oNode) //判断是否自己赋值自己 { return *this; } delete m_lpszChar; //释放原字符数组空间 m_lpszChar = new char[strlen(oNode.m_lpszChar)+1]; //new字符数组空间。 if( m_lpszChar==NULL ) { cout << "内存分配失败。" << endl; exit(1); } strcpy(m_lpszChar, oNode.m_lpszChar); m_iValue = oNode.m_iValue; //节点值初为0 cout << "调用了重载'='运算符Node:" << m_lpszChar << endl; return *this; } //CNodeArray类的构造函数 CNodeArray::CNodeArray(int iTotalNodeNum) //节点数组构造函数。 { for (int i=0; i<iTotalNodeNum; i++) { m_pNode[i] = NULL; //指针数组初始化,数组内的指针全部指向NULL。 } m_aLength = iTotalNodeNum; //数组长度设置。 m_aCurrentTop = 0; //当前节点设置为0。 cout << "调用了构造函数CNodeArray:" << endl; } //CNodeArray的拷贝构造函数。const引用作参数,可保证实参的安全性。 CNodeArray::CNodeArray(const CNodeArray &oCNodeArray) { //在[0~m_aCurrentTop-1]之间,有Node节点,所以需要新建节点。 for (int i=0; i<oCNodeArray.m_aCurrentTop; i++) { //创建一个新节点,并将oCNodeArray上对应节点的内容复制过来。 m_pNode[i] = new Node(oCNodeArray.m_pNode[i]->m_lpszChar, oCNodeArray.m_pNode[i]->m_iValue); if (m_pNode[i] == NULL) //判断内存分配是否成功。 { cout << "内存分配失败!" << endl; exit(1); } } //在[m_aCurrentTop~m_aLength-1]之间,没有Node节点,全为NULL。 for (i=oCNodeArray.m_aCurrentTop; i<oCNodeArray.m_aLength; i++) { m_pNode[i] = NULL; } m_aLength = oCNodeArray.m_aLength; //复制数组长度的值。 m_aCurrentTop = oCNodeArray.m_aCurrentTop; //复制当前节点标号值。 cout << "调用了拷贝构造函数CNodeArray:" << endl; } //析构函数。 CNodeArray::~CNodeArray(void) //析构函数 { for (int i=0; i<m_aCurrentTop; i++) { delete m_pNode[i]; //自动调用~Node()。 } cout << "调用了析构函数CNodeArray。" << endl; } //插入一个节点。插入位置在m_aCurrentTop处。这里通过指针数组里的指针操作其所指向的节点。 //其插入和删除有点类似堆栈的性质:只在top端,插入,删除。 bool CNodeArray::Insert(const Node &oNode) //插入一个节点 { //将要插入的节点复制到节点数组中。 m_pNode[m_aCurrentTop] = new Node(oNode.m_lpszChar, oNode.m_iValue); if (m_pNode[m_aCurrentTop] == NULL) { cout << "创建节点失败!" << endl; exit(1); } m_aCurrentTop++; //将当前节点值m_aCurrentTop+1,下一次插入的位置。 cout << "插入了一个节点: " << oNode.m_lpszChar << endl; return true; } //删除一个节点。每次删除都删除m_aCurrentTop-1的对应节点。相当于节点出栈。 bool CNodeArray::Del(void) //删除一个节点 { if (!IsEmpty()) //如果指针数组非空,则执行删除操作。 { m_aCurrentTop--; //首先将当前节点值减1。当前节点实际上还没有内容。 cout << "删除的节点名字为:" << m_pNode[m_aCurrentTop]->m_lpszChar << endl; delete m_pNode[m_aCurrentTop]; //释放当前节点 return true; } else { cout << "节点数组为空。不能够执行删除操作。Is Empty\n"; return false; } } //判断节点指针数组中是否有节点。 bool CNodeArray::IsEmpty(void) { if (m_aCurrentTop == 0) { return true; //为空返回真。 } else { return false; //不为空,返回假。 } } //CNodeArray的','运算符重载。 const CNodeArray & CNodeArray::operator,(const CNodeArray &oCNodeArray) { return oCNodeArray; //直接返回第二操作数。 } //CNodeArray的'[]'运算符重载。 char *CNodeArray::operator[](int i) { if ((i < m_aCurrentTop)&&(m_aCurrentTop >=0)) { return m_pNode[i]->m_lpszChar; //返回第i个节点的字符串。 } else { return ("数组越界。"); } } //赋值运算符重载。其重载函数体与拷贝构造函数相同,可调用完成。但重载赋值运算符需要 //首先释放,调用对象的相关动态内存。 CNodeArray & CNodeArray::operator=(const CNodeArray &oCNodeArray) { if (this == &oCNodeArray) //首先判断是否自己赋值给自己 { return *this; } //这里需要考虑两个对象的m_aLength属性是否相同,是否一样大,否则会产生数组越界的问题。 //这里的指针数组是非动态的,不可调整大小。 if (m_aLength != oCNodeArray.m_aLength) { cout << "复制出错。" << endl; return *this; } //首先进行释放工作,释放this对象所使用到的所有动态内存空间。 for (int i=0; i<m_aCurrentTop; i++) { delete m_pNode[i]; //释放指针数组中的每个指针所指向的动态内存空间,=NULL。 //m_pNode[i] = NULL; } //此后可进行对象复制工作。此处是一个深度复制过程,在复制中需要新建(new)Node //类型的对象数组空间,所以用了Node的构造函数。 //在[0~m_aCurrentTop-1]之间,有Node节点,所以需要新建节点。 for (i=0; i<oCNodeArray.m_aCurrentTop; i++) { //创建一个新节点,并将oCNodeArray上对应节点的内容复制过来。 m_pNode[i] = new Node(oCNodeArray.m_pNode[i]->m_lpszChar, oCNodeArray.m_pNode[i]->m_iValue); if (m_pNode[i] == NULL) //判断内存分配是否成功。 { cout << "内存分配失败!" << endl; exit(1); } } //在[m_aCurrentTop~m_aLength-1]之间,全为NULL。 for (i=oCNodeArray.m_aCurrentTop; i<oCNodeArray.m_aLength; i++) { m_pNode[i] = NULL; } m_aLength = oCNodeArray.m_aLength; //复制数组长度的值。 m_aCurrentTop = oCNodeArray.m_aCurrentTop; //复制当前节点标号值。 cout << "调用重载运算符'='CNodeArray:" << endl; return *this; } //重载new void *CNodeArray::operator new(size_t size) { cout << "自定义的 CNodeArray new\n"; return malloc(size); } //重载delete void CNodeArray::operator delete(void *p) { cout << "自定义的 CNodeArray delete\n"; free(p); } //重载输出运算符, ostream & operator << (ostream & scout, CNodeArray obj) { scout << obj.m_pNode[obj.m_aCurrentTop-1]->m_lpszChar << ","; scout << obj.m_pNode[obj.m_aCurrentTop-1]->m_iValue << ","; scout << obj.m_aLength << ","; scout << obj.m_aCurrentTop << endl; return scout; } //重载输入运算符 istream & operator >> (istream &scin, CNodeArray &obj) { int iTemp = 0; char *lpszChar = new char[100]; cout << "请输入操作下标:"; scin >> iTemp; cout << "请输入节点值:"; scin >> obj.m_pNode[iTemp]->m_iValue; cout << "节点原名字为:" << obj.m_pNode[iTemp]->m_lpszChar << endl; cout << "请输入节点新名字:" << endl; scin.get(); scin.getline(lpszChar,20); //从输入流中取得一行,新节点名字。 delete obj.m_pNode[iTemp]->m_lpszChar; //释放原来的内存空间。 obj.m_pNode[iTemp]->m_lpszChar = lpszChar; //指向新的内存空间。 cout << "现名字为:" << obj.m_pNode[iTemp]->m_lpszChar << endl; return scin; }